#%%
from strategy_mode import TradingStrategy_sum_03 as Strgs
import strategy_Main
import updateing_cache
from OtherTools import filetool
from live_cals import Main_func, refrishing
from live_plot import Main_plot

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import plotly.graph_objects as go
from plotly.subplots import make_subplots

import pandas as pd
import datetime
import time
import json
import gc
from rich import print


#%%


with open(r"config_live.json", mode="r") as f:
    res = f.read()
live_update_config = json.loads(res)

on_reflash = 0

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
left_width = "290px"
app.layout = html.Div(
    [
        dcc.Interval(
            id="interval_component",
            interval=live_update_config["interval_reflash_speed"],  # in milliseconds
            n_intervals=0,
        ),
        dcc.Interval(
            id="table_reflash",
            interval=30000,  # in milliseconds
            n_intervals=0,
        ),
        html.Div(
            [
                dcc.Graph(
                    id="live-update-graph",
                    style={
                        "left": "5px",
                        "right": "320px",
                        "top": "15px",
                        "bottom": "5px",
                        "position": "absolute",
                    },
                ),
            ],
        ),
        html.Div(
            [
                html.Div(
                    id="stock_detail",
                    style={
                        "position": "absolute",
                        "font_size": "10px",
                        "right": "25px",
                        "top": "5px",
                        "display": "none",
                        # "height":"200px",
                    },
                ),
                html.Div(
                    [
                        html.Div(
                            [
                                dcc.Dropdown(
                                    id="DropDown_Line_select",
                                    options=[
                                        {"label": "Moveing Average", "value": "ma"},
                                        {"label": "root", "value": "root"},
                                        {
                                            "label": "polynomial_X",
                                            "value": "x",
                                        },
                                        {"label": "Zero Axis", "value": "zero"},
                                        {"label": "Q", "value": "q"},
                                    ],
                                    multi=True,
                                    value=[
                                        "root",
                                        # "x",
                                        "q",
                                        "zero",
                                        # "ma",
                                    ],
                                    # value=[],
                                )
                            ],
                        ),
                        html.Div(
                            [
                                html.Div(
                                    dcc.Input(
                                        id="input_box_1",
                                        type="text",
                                        placeholder="股票代码 601398",
                                        style={
                                            "width": left_width,
                                            "margin-top": "10px",
                                        },
                                        value=live_update_config["Input_code"],
                                    ),
                                ),
                            ],
                            # style={"width": "100%"},
                        ),
                        dcc.Dropdown(
                            id="time_range",
                            options=[
                                {"label": "5 分钟", "value": "5"},
                                {"label": "15 分钟", "value": "15"},
                                {"label": "30 分钟", "value": "30"},
                                {"label": "60 分钟", "value": "60"},
                                {"label": "120 分钟", "value": "120"},
                            ],
                            value=live_update_config["Dropdown_pre"],
                            style={"width": left_width, "margin-top": "10px"},
                        ),
                        dcc.DatePickerRange(
                            id="date_picker_range",
                            min_date_allowed=datetime.date(1990, 1, 1),
                            max_date_allowed=datetime.datetime.strptime(
                                (
                                    datetime.datetime.now() + datetime.timedelta(days=5)
                                ).strftime("%Y-%m-%d"),
                                "%Y-%m-%d",
                            ),
                            display_format="Y-M-D",
                            start_date=datetime.datetime.strptime(
                                (live_update_config["start_date"]),
                                "%Y-%m-%d",
                            ),
                            end_date=datetime.datetime.strptime(
                                (
                                    datetime.datetime.now() + datetime.timedelta(days=4)
                                ).strftime("%Y-%m-%d"),
                                "%Y-%m-%d",
                            ),
                            style={
                                "width": left_width,
                                "margin-top": "10px",
                            },
                        ),
                        html.Button(
                            id="submit_button_state",
                            n_clicks=0,
                            children="Submit / 确认",
                            style={"width": left_width, "margin-top": "10px"},
                        ),
                        html.Div(
                            [
                                dcc.RadioItems(
                                    id="mode_selecter",
                                    options=[
                                        {"label": x, "value": x}
                                        for x in ["normal", "simulation"]
                                    ],
                                    value="normal",
                                ),
                            ],
                            style={"columns": "2", "margin-top": "5px"},
                        ),
                    ],
                    style={
                        "width": "290px",
                        "top": "30px",
                        "position": "absolute",
                    },
                ),
                html.Div(
                    children=[
                        html.Div(
                            id="bottom_Div",
                            children=[
                                html.Div(
                                    id="info_table",
                                    style={
                                        # "height": "500px",
                                        "margin-bottom": "0px",
                                        "width": "350px",
                                        "overflow-y": "scroll",
                                        "overflow-x": "hidden",
                                    },
                                    children=[],
                                ),
                                dcc.Input(
                                    id="AvableCashs",
                                    type="number",
                                    placeholder="输入初始金额",
                                    style={
                                        "width": left_width,
                                        "margin-top": "10px",
                                        "display": "none",
                                    },
                                    value=1000000,
                                ),
                            ],
                        ),
                        html.Button(
                            id="reflash_button_state",
                            n_clicks=0,
                            children="reflash / 刷新",
                            style={"width": left_width, "margin-top": "10px"},
                        ),
                    ],
                    style={
                        "width": "290px",
                        "bottom": "30px",
                        "position": "absolute",
                    },
                ),
                html.Div(
                    id="table_data",
                    # style={"display": "none"},
                    children=[
                        json.dumps(
                            {
                                "code": "'300999",
                                "period/year": 0.23,
                                "finalValue": 163281.51,
                                "%_pre_year": 7.21063,
                                "%_increase": 0.63282,
                                "Change_Rate": 0.73663,
                                "Maxmut_Loss": 0.9738,
                            }
                        )
                    ],
                ),
            ],
            style={
                "width": "310px",
                "right": "10px",
                "bottom": "5px",
                "top": "5px",
                "position": "absolute",
                "font_size": "10px",
            },
        ),
    ],
)


@app.callback(
    Output(component_id="bottom_Div", component_property="children"),
    Input("mode_selecter", "value"),
    State(component_id="bottom_Div", component_property="children"),
)
def mode_change(mode_selecter, children):
    if mode_selecter == "simulation":
        children = [
            html.Div(
                id="info_table",
                style={
                    "margin-bottom": "0px",
                    "width": "350px",
                    "overflow-y": "scroll",
                    "overflow-x": "hidden",
                },
                children=[],
            ),
            dcc.Input(
                id="AvableCashs",
                type="number",
                placeholder="输入初始金额",
                style={
                    "width": left_width,
                    "margin-top": "10px",
                },
                value=1000000,
            ),
        ]
        return children

    else:
        children = [
            html.Div(
                id="info_table",
                style={
                    "margin-bottom": "0px",
                    "width": "350px",
                    "overflow-y": "scroll",
                    "overflow-x": "hidden",
                },
                children=[],
            ),
            dcc.Input(
                id="AvableCashs",
                type="number",
                placeholder="输入初始金额",
                style={"width": left_width, "margin-top": "10px", "display": "none"},
                value=1000000,
            ),
        ]
        return children


@app.callback(
    Output("table_data", "children"),
    Input("reflash_button_state", "n_clicks"),
    State("stock_detail", "children"),
    State("table_data", "children"),
    State("AvableCashs", "value"),
)
def simulation(reflash_button_state, stock_detail, table_data, AvableCashs):
    if reflash_button_state % 2 == 1:
        stock_detail = json.loads(stock_detail)
        with open(r"config_path.json", mode="r") as f:
            res = f.read()
        path_config = json.loads(res)
        dic, df = strategy_Main.Strategy_Main_3(
            Strgs,
            code=stock_detail["Input_code"],
            pre=stock_detail["Dropdown_pre"],
            simulation_type="run",
            AvableCash=100000,
            tradePersentDic={"x1": 1},
            fees_Persent=0.0035,
            Cutting_start_date=stock_detail["start_date"],
            GroupOfLines=4,
            printLens=60,
            keyls=["Avg"],
            dirDic=stock_detail["path"],
            import_in=True
        )
        table_data = [json.dumps(dic)]
        return table_data


@app.callback(
    Output(component_id="info_table", component_property="children"),
    Input(component_id="stock_detail", component_property="children"),
    Input(component_id="table_data", component_property="children"),
    Input("table_reflash", "n_intervals"),
    State("mode_selecter", "value"),
    State(component_id="info_table", component_property="children"),
)
def trade_block(
    stock_detail,
    table_data,
    table_reflash,
    mode_selecter,
    info_table,
):
    if mode_selecter == "simulation":
        table_data = json.loads(table_data)
        df = pd.DataFrame(table_data)
        info_table = [
            html.Table(
                [
                    html.Thead(
                        html.Tr(
                            [
                                html.Th(col, style={"color": "gray"})
                                for col in df.columns.tolist()
                            ]
                        )
                    ),
                    html.Tbody(
                        [
                            html.Tr(
                                [
                                    html.Td(
                                        "{:.2f}".format(float(df.iloc[i][col]))
                                        if isinstance(df.iloc[i][col], float)
                                        else df.iloc[i][col],
                                        # style={},
                                    )
                                    for col in df.columns.tolist()
                                ]
                            )
                            for i in range(min(len(df), 10))
                        ]
                    ),
                ]
            )
        ]
        return info_table
    else:
        stock_detail = json.loads(stock_detail)
        paths = stock_detail["path"]
        path = paths["Main"] + paths["ticker"] + stock_detail["Input_code"] + ".csv"
        df = pd.read_csv(path)
        df["T"] = pd.to_datetime(df["datetime"])
        df.sort_values(by=["datetime"], axis=0, ascending=False, inplace=True)
        df = df.iloc[0:10]
        df["time"] = df["datetime"].apply(lambda x: str(x).split(" ")[-1])
        info_table = [
            html.Table(
                [
                    html.Thead(
                        html.Tr(
                            [
                                html.Th(col, style={"color": "gray"})
                                for col in ["time", "price", "volume", "change"]
                            ]
                        )
                    ),
                    html.Tbody(
                        [
                            html.Tr(
                                [
                                    html.Td(
                                        "{:.2f}".format(float(df.iloc[i][col]))
                                        if isinstance(df.iloc[i][col], float)
                                        else df.iloc[i][col],
                                        style={
                                            "color": "red"
                                            if df.iloc[i]["type"] == 1
                                            else (
                                                "forestgreen"
                                                if df.iloc[i]["type"] == -1
                                                else "slategrey"
                                            ),
                                            # "height": "6px",
                                            # "width": "20px"
                                            # if col == "time"
                                            # else (
                                            #     "15px"
                                            #     if col == "price"
                                            #     else ("40px" if col == "volume" else "15px")
                                            # ),
                                        },
                                    )
                                    for col in ["time", "price", "volume", "change"]
                                ]
                            )
                            for i in range(min(len(df), 10))
                        ]
                    ),
                ]
            )
        ]
        return info_table


@app.callback(
    Output(component_id="stock_detail", component_property="children"),
    Input("submit_button_state", "n_clicks"),
    State("DropDown_Line_select", "value"),
    State("mode_selecter", "value"),
    State("date_picker_range", "start_date"),
    State("date_picker_range", "end_date"),
    State("input_box_1", "value"),
    State("time_range", "value"),
)
def update_output(
    submit_button_state,
    DropDown_Line_select,
    mode_selecter,
    start_date,
    end_date,
    input_box_1,
    time_range,
):
    if input_box_1 != None:
        code = input_box_1
        if len(code) == 6 and ("'" or '"' or "*") not in code:

            start_date = start_date.split("T")[0]
            end_date = end_date.split("T")[0]
            refrishing.refrish_config(
                time_range=time_range,
                code=code,
                start_date=start_date,
            )
            with open(r"config_path.json", mode="r") as f:
                res = f.read()
            path = json.loads(res)
            gc.collect()
            return json.dumps(
                {
                    "Input_code": input_box_1,
                    "Dropdown_pre": time_range,
                    "start_date": start_date,
                    "end_date": end_date,
                    "lines": DropDown_Line_select,
                    "mode_selecter": mode_selecter,
                    "path": path,
                }
            )
        else:
            return "error"
    return "error"


def remove_columns(
    input_data=["ma", "root", "x", "zero"],
    col_les=[],
    matching_key="ma",
    col_key="Avg_ma_",
):
    temp = col_les.copy()
    if matching_key not in input_data:
        for col in col_les:
            if col_key in col or col.startswith(col_key):
                temp.remove(col)
    return temp


@app.callback(
    Output("live-update-graph", "figure"),
    Input("interval_component", "n_intervals"),
    Input("submit_button_state", "n_clicks"),
    Input(component_id="stock_detail", component_property="children"),
)
def update_graph_live(
    interval_component,
    submit_button_state,
    stock_detail,
):

    with open(r"config_path.json", mode="r") as f:
        res = f.read()
    path = json.loads(res)
    stock_detail = json.loads(stock_detail)
    if "error" != stock_detail:
        temppath = (
            path["Main"]
            + path["temp"]
            + "{}_{}.csv".format(
                stock_detail["Input_code"], stock_detail["Dropdown_pre"]
            )
        )
        if (
            filetool.FileCheck(temppath) == False
            and stock_detail["mode_selecter"] == "normal"
        ):
            updateing_cache.cache_Loop(stock_detail["Input_code"])

        df = pd.read_csv(temppath)
        df["timestamp"] = pd.to_datetime(df["date"])
        start = datetime.datetime.strptime(
            (stock_detail["start_date"] + "T01:01:01"),
            "%Y-%m-%dT%H:%M:%S",
        )
        end = datetime.datetime.strptime(
            (stock_detail["end_date"] + "T01:01:01"),
            "%Y-%m-%dT%H:%M:%S",
        )

        df = df[(df["timestamp"] >= start) & (df["timestamp"] <= end)]
        sorter = 0
        col_Les = df.columns.tolist()

        col_Les = remove_columns(
            input_data=stock_detail["lines"],
            col_les=col_Les,
            matching_key="ma",
            col_key="Avg_ma_",
        )
        col_Les = remove_columns(
            input_data=stock_detail["lines"],
            col_les=col_Les,
            matching_key="q",
            col_key="Q_",
        )
        col_Les = remove_columns(
            input_data=stock_detail["lines"],
            col_les=col_Les,
            matching_key="root",
            col_key="xss_",
        )
        col_Les = remove_columns(
            input_data=stock_detail["lines"],
            col_les=col_Les,
            matching_key="root",
            col_key="ys_",
        )
        col_Les = remove_columns(
            input_data=stock_detail["lines"],
            col_les=col_Les,
            matching_key="x",
            col_key="polynomial_X_",
        )
        if "zero" in stock_detail["lines"]:
            df["zero"] = 0

        Main_plots = Main_plot.Main_Candlestick_plot(df[col_Les])
        gc.collect()
        return Main_plots


if __name__ == "__main__":
    app.run_server(debug=True)
